package com.example.demo.thread.loopPrint;

import antlr.debug.SemanticPredicateAdapter;

import java.util.concurrent.Semaphore;

/**
 * Semaphore：用来控制同时访问某个特定资源的操作数量，或者同时执行某个制定操作的数量。Semaphore内部维护了一个计数器，其值为可以访问的共享资源的个数。
 *
 * 一个线程要访问共享资源，先使用acquire()方法获得信号量，如果信号量的计数器值大于等于1，意味着有共享资源可以访问，则使其计数器值减去1，再访问共享资源。如果计数器值为0,线程进入休眠。
 *
 * 当某个线程使用完共享资源后，使用release()释放信号量，并将信号量内部的计数器加1，之前进入休眠的线程将被唤醒并再次试图获得信号量。
 */
public class SemaphoreABC {
    private static Semaphore s1 = new Semaphore(1);
    private static Semaphore s2 = new Semaphore(0);
    private static Semaphore s3 = new Semaphore(0);

    private void printABC(Semaphore currentThread,Semaphore nextThread){
        for (int i = 0; i < 10; i++) {
            try {
                currentThread.acquire();//阻塞当前线程，即信号量的计数器减1为0
                System.out.println(Thread.currentThread().getName() );
                nextThread.release();//唤醒下一个线程，即信号量的计数器加1
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        SemaphoreABC semaphoreABC = new SemaphoreABC();
        new Thread(() -> semaphoreABC.printABC(s1,s2), "A").start();
        new Thread(() -> semaphoreABC.printABC(s2,s3), "B").start();
        new Thread(() -> semaphoreABC.printABC(s3,s1), "C").start();
    }
}
